from django.utils.translation import ugettext_lazy as _
from django.utils import translation
from django.conf import settings
from datetime import datetime
from d115.middleware import ThreadLocals

if hasattr(settings, "GEODJANGO") and settings.GEODJANGO:
    from django.contrib.gis.db import models
    from django.contrib.gis import admin
    ModelAdmin = admin.OSMGeoAdmin
else:
    from django.db import models
    from django.contrib import admin
    ModelAdmin = admin.ModelAdmin

def get_custom_user_model():
    try:
        from django.conf import settings
        return settings.CUSTOM_USER_MODEL
    except: 
        return "auth.User"

class AuditMixin(models.Model):
    created = models.DateTimeField(blank=True, null=True, editable=False, verbose_name=_("Created on"))
    modified = models.DateTimeField(blank=True, null=True, editable=False, verbose_name=_("Last modified on"))
    created_by = models.CharField(max_length=255, blank=True, null=True, editable=False, verbose_name=_("Created by"))
    modified_by = models.CharField(max_length=255, blank=True, null=True, editable=False, verbose_name=_("Last modified by"))

    class Meta:
        abstract = True
        ordering = ['-created',]

    def save(self, *args, **kwargs):
        dtn = datetime.now()
        if not self.created:
            self.created = dtn
        self.modified = dtn
        try:
            cu = ThreadLocals.get_current_user().username
        except:
            cu = ''
        if not self.created_by:
            self.created_by = cu
        self.modified_by = cu
        super(AuditMixin, self).save(*args, **kwargs)

class AuditAdminMixin(ModelAdmin):
    """
    Use this for the ModelAdmin of any AuditMixin descendant.  
    """
    readonly_fields = ['created', 'created_by', 'modified', 'modified_by']
    list_display = ['format_created', 'created_by', 'format_modified', 'modified_by']
    list_filter = ['created', 'created_by', 'modified', 'modified_by']

    def format_created(self, obj):
        return obj.created.strftime('%d %b %Y %H:%M')
    format_created.short_description = _("Created on")
    format_created.admin_order_field = 'created'

    def format_modified(self, obj):
        return obj.modified.strftime('%d %b %Y %H:%M')
    format_modified.short_description = _("Last modified on")
    format_modified.admin_order_field = 'modified'

class PositionMixin(models.Model):
    """
    Use this mixin to allow ordering of your model by an integer 'position' field.  If you don't explicitly set the 'position' field, it is automatically set to the next available position at save time.  
    """
    position = models.IntegerField(blank=True, null=True, verbose_name=_("Position"))
    
    class Meta:
        abstract = True
        ordering = ['position',]
    
    def save(self, *args, **kwargs):
        model = self.__class__
        if self.position is None:
            try:
                last = model.objects.order_by('-position')[0]
                self.position = (last.position or 0) + 1
            except IndexError:
                self.position = 0
        return super(PositionMixin, self).save(*args, **kwargs)

class PositionAdminMixin(ModelAdmin):
    """
    Use this for the ModelAdmin of any PositionMixin descendant.  
    """
    class Media:
        js = (
#                '/media/js/jquery.min.js',
#                '/media/js/jquery-ui.min.js',
#                '/media/js/admin-list-reorder.js',
                )
    list_display = ['position',]
    list_per_page = 1000
    list_editable = ['position',]

class NomenclatureMixin(PositionMixin):
    """
    Use this for any model which should have a "name" and a "position".  Sets the default __unicode__ method to return the "name" field.  
    """
    name = models.CharField(max_length=512, verbose_name = _("Name"))

    class Meta(PositionMixin.Meta):
        abstract = True
        ordering = ['position', 'name']
    
    def __unicode__(self):
        return u"%s" % self.name


class NomenclatureAdminMixin(ModelAdmin):
    """
    Use this for the ModelAdmin of any NomenclatureMixin descendant.  
    """
    class Media:
        js = (
#                '/media/js/jquery.min.js',
#                '/media/js/jquery-ui.min.js',
#                '/media/js/admin-list-reorder.js',
                )
    list_display = ['name', 'position']
    list_per_page = 1000
    list_editable = ['position']
    search_fields = ['name',]

"""
class TranslatableManager(models.Manager):
    def get_query_set(self):
        if translation.get_language() == settings.LANGUAGE_CODE:
            return super(TranslatableManager, self).get_query_set()
        app = self.model._meta.app_label
        tmodel = models.get_model(app, self.model._meta.object_name + "Translation")
        ids = tmodel.objects.filter(language=translation.get_language()).values_list('ofk__id', flat=True)
        return super(TranslatableManager, self).get_query_set().filter(id__in=ids)
"""

class Translatable(models.Model):
    #objects = TranslatableManager()
    def __unicode__field(self):
        return 'name'

    def _get_default_translation(self):
        language = translation.get_language()
        if language == settings.LANGUAGE_CODE:
            return self
        else:
            try:
                return self.translations.get(language=language)
            except:
                try:
                    return self.translations.get(language='en')
                except:
                    pass
        return self
    default_translation = property(_get_default_translation)

    def __unicode__(self):
        language = translation.get_language()
        field = self.__unicode__field()
        if language == settings.LANGUAGE_CODE:
            return u"%s" % getattr(self, field)
        try:
            return u"%s" % getattr(self.translations.get(language=language), field)
        except:
            try:
                return u"%s" % getattr(self.translations.get(language='en'), field)
            except:
                pass
        return u"%s" % getattr(self, field)

    class Meta:
        abstract = True
